package com.ruoyi.project.emmanuel.account.service.impl;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ToolUtils;
import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.common.utils.text.Convert;
import com.ruoyi.framework.datasource.DataSourceUtils;
import com.ruoyi.project.emmanuel.account.domain.AccountMoney;
import com.ruoyi.project.emmanuel.account.mapper.AccountAccountMapper;
import com.ruoyi.project.emmanuel.account.mapper.AccountClassMapper;
import com.ruoyi.project.emmanuel.account.mapper.AccountMoneyMapper;
import com.ruoyi.project.emmanuel.account.service.IAccountMoneyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * 记账详情Service业务层处理
 *
 * @author ruoyi
 * @date 2022-01-21
 */
@Service
public class AccountMoneyServiceImpl implements IAccountMoneyService {

    @Autowired
    private AccountMoneyMapper accountMoneyMapper;

    @Autowired
    private AccountAccountMapper accountAccountMapper;

    @Autowired
    private AccountClassMapper accountClassMapper;

    /**
     * 查询记账详情
     *
     * @param id 记账详情主键
     * @return 记账详情
     */
    @Override
    public AccountMoney selectAccountMoneyById(Long id) {
        AccountMoney accountMoney = accountMoneyMapper.selectAccountMoneyById(id);
        return accountMoney;
    }

    /**
     * 查询记账详情列表
     *
     * @param accountMoney 记账详情
     * @return 记账详情
     */
    @Override
    public List<AccountMoney> selectAccountMoneyList(AccountMoney accountMoney,String classIds) {
        String[] classIdList = null;
        if (StringUtils.isNotEmpty(classIds)){
            classIdList = Convert.toStrArray(classIds);
        }
        return accountMoneyMapper.selectAccountMoneyList(accountMoney, classIdList);
    }

    /**
     * 新增记账详情
     *
     * @param accountMoney 记账详情
     * @return 结果
     */
    @Override
    public int insertAccountMoney(AccountMoney accountMoney) {
        // 先查询账单是否停用
        this.isAccountVisible(accountMoney);
        // type非数据库字段，1是支出,0是收入
        String type = accountMoney.getType();
        // 如果不选择默认当天
        if (ToolUtils.isEmpty(accountMoney.getMoneyDate())) {
            accountMoney.setMoneyDate(DateUtils.getNowDate());
        }

        accountMoney.setCreateBy(ShiroUtils.getLoginName());
        return accountMoneyMapper.insertAccountMoney(accountMoney);
    }

    /**
     * 修改记账详情
     *
     * @param accountMoney 记账详情
     * @return 结果
     */
    @Override
    public int updateAccountMoney(AccountMoney accountMoney) {
        // 先查询账单是否停用
        this.isAccountVisible(accountMoney);
        // type非数据库字段，1是支出,0是收入
        String type = accountMoney.getType();
        accountMoney.setUpdateBy(ShiroUtils.getLoginName());
        return accountMoneyMapper.updateAccountMoney(accountMoney);
    }

    /**
     * 查询account的状态
     *
     * @param accountMoney
     */
    private void isAccountVisible(AccountMoney accountMoney) {
        String isVisible = accountAccountMapper.isAccountVisible(accountMoney);
        if (ToolUtils.isNotEmpty(isVisible) && !Objects.equals("0",isVisible)){
            throw new RuntimeException("当前账单已停用，不可变更");
        }
    }

    /**
     * 批量删除记账详情
     *
     * @param ids 需要删除的记账详情主键
     * @return 结果
     */
    @Override
    public int deleteAccountMoneyByIds(String ids,Long accountId) {
        // 先查询账单是否停用
        AccountMoney accountMoney = new AccountMoney();
        accountMoney.setAccountId(accountId);
        this.isAccountVisible(accountMoney);
        return accountMoneyMapper.deleteAccountMoneyByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除记账详情信息
     *
     * @param id 记账详情主键
     * @return 结果
     */
    @Override
    public int deleteAccountMoneyById(Long id) {
        return accountMoneyMapper.deleteAccountMoneyById(id);
    }

    /**
     * 月统计 - 行转列
     */
    @Override
    public  List<Map<String,Object>> selectMoneyByClass(Long accountId) {
        Long userId = ShiroUtils.getUserId();
        // 查询行转列值
        String rowSum = accountClassMapper.selectClassRow();

        // 获取数据库类型
        String dbType = DataSourceUtils.getDbType();

        List<Map<String,Object>> mapList = new ArrayList<>();

        // SQLite数据库
        if (StringUtils.equalsAnyIgnoreCase(dbType, DataSourceUtils.SQLITE)){
             mapList = accountMoneyMapper.selectMoneyByClass_SQLITE(accountId,userId,rowSum);
        }
        // mysql数据库
        if (StringUtils.equalsAnyIgnoreCase(dbType, DataSourceUtils.MYSQL)){
             mapList =  accountMoneyMapper.selectMoneyByClass(accountId,userId,rowSum);
        }

        if (ToolUtils.isNotEmpty(mapList)){

            Map<String, Object> map = mapList.get(mapList.size() - 1);
            if (ToolUtils.isEmpty(map.get("money_date"))){
                map.put("money_date", "总   计");
            };

            // 计算各列的平均值
            Map<String, Object> mapAvg = calculateAverages(mapList);
            mapList.add(mapAvg);
        }

        return mapList;
    }

    // 计算 mapList 中的所有列的平均值
    private Map<String, Object> calculateAverages(List<Map<String, Object>> mapList) {
        Map<String, Object> averages = new HashMap<>();
        int count = mapList.size() - 1;  // 排除"总计"行
        BigDecimal sum;
        // 计算每一列的平均值
        for (String key : mapList.get(0).keySet()) {
            if (!key.equals("money_date")) {  // 排除 "money_date" 列
                sum = BigDecimal.ZERO;
                for (int i = 0; i < mapList.size() - 1; i++) {
                    Map<String, Object> map = mapList.get(i);
                    sum = sum.add(new BigDecimal(String.valueOf(map.get(key))));
                }
                averages.put(key, sum.divide(BigDecimal.valueOf(count), 2, BigDecimal.ROUND_HALF_UP));  // 使用 BigDecimal 计算平均值，并四舍五入保留2位小数
            }
        }
        averages.put("money_date","平均值");
        return averages;
    }
}
